#ifndef __M_CLIENT_H__
#define __M_CLIENT_H__

#include "connection.hpp"
#include "worker.hpp"

using namespace zhong;

class ConsumerClient
{
public:
    using ptr = std::shared_ptr<ConsumerClient>;
    ConsumerClient(const Channel::ptr &channel) : _channel(channel) {}
    // // 选择虚拟机
    bool selectVirtualHost(const std::string &host_name)
    {
        return _channel->selectVirtualHost(host_name);
    }
    // 声明队列
    bool declareQueue(const std::string &queue_name,
                      bool durable,
                      bool exclusive,
                      bool auto_delete,
                      const google::protobuf::Map<std::string, std::string> &args_map)
    {
        return _channel->declareQueue(queue_name, durable, exclusive, auto_delete, args_map);
    }
    // 删除队列
    void deleteQueue(const std::string &queue_name)
    {
        return _channel->deleteQueue(queue_name);
    }
    // 绑定队列
    bool bind(const std::string &exchange_name, const std::string &queue_name, const std::string &binding_key)
    {
        return _channel->bind(exchange_name, queue_name, binding_key);
    }
    // 取消队列绑定
    void unBind(const std::string &exchange_name, const std::string &queue_name)
    {
        return _channel->unBind(exchange_name, queue_name);
    }
    // 订阅队列信息
    bool basicConsume(const std::string &consumer_tag, const std::string &queue_name, bool auto_ack)
    {
        ConsumerCallback func = std::bind(&ConsumerClient::callback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
        return _channel->basicConsume(consumer_tag, queue_name, auto_ack, func);
    }
    // 手动进行消息确认
    void basicAck(const std::string &message_id)
    {
        return _channel->basicAck(message_id);
    }
    // 取消订阅
    void basicCancel()
    {
        return _channel->basicCancel();
    }

private:
    void callback(const std::string &consumer_tag, const zhong::BasicProperties *bp, const std::string &body)
    {
        _channel->basicAck(bp->id()); // 是否需要增加自动确认标志

        // 接下来就是针对这个回调函数进行处理了
    }

private:
    Channel::ptr _channel;
};

class ProducerClient
{
public:
    using ptr = std::shared_ptr<ProducerClient>;
    ProducerClient(const Channel::ptr &channel) : _channel(channel) {}
    // 选择虚拟机
    bool selectVirtualHost(const std::string &host_name)
    {
        return _channel->selectVirtualHost(host_name);
    }
    // 声明交换机
    bool declareExchange(const std::string &exchange_name,
                         ExchangeType type,
                         bool durable,
                         bool auto_delete,
                         const google::protobuf::Map<std::string, std::string> &args_map)
    {
        return _channel->declareExchange(exchange_name, type, durable, auto_delete, args_map);
    }
    // 删除交换机
    void deleteExchange(const std::string &exchange_name)
    {
        return _channel->deleteExchange(exchange_name);
    }
    // 消息发布
    bool basicPublish(const std::string &exchange_name, const BasicProperties *bp, const std::string &body)
    {
        return _channel->basicPublish(exchange_name, bp, body);
    }

private:
    Channel::ptr _channel;
};

class ManagerCilent
{
public:
    using ptr = std::shared_ptr<ManagerCilent>;
    ManagerCilent(const Channel::ptr &channel) : _channel(channel) {}
    bool declareVirtualHost(const std::string &host_name, bool durable)
    {
        return _channel->declareVirtualHost(host_name, durable);
    }
    void deleteVirtualHost(const std::string &host_name)
    {
        return _channel->deleteVirtualHost(host_name);
    }

private:
    Channel::ptr _channel;
};

#endif